#include <iostream>
using namespace std;
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <string>
#include <assert.h>
#include <stdlib.h>
#include<vector>
void Count(int cnt){
    while(cnt){
        printf("cnt:%d",cnt);
        fflush(stdout);
        cnt--;
        sleep(1);
    }
}

void handler(int signo)
{
    cout << "进程捕捉到了一个信号，信号编号是" << signo << endl;
    //Count(20);
    // exit(1);
    // alarm(1);
}

void errno_print(const char *ret)
{
    printf("%s输入的格式有误,应该加上pid/sign\n", ret);
}

static vector<int> sigarr = {2,3};//同时屏蔽2个信号

static void show_pending(const sigset_t &pending)
{
    for (int signo = 32; signo >= 1; signo--)
    {
        //pending
        if(sigismember(&pending,signo)){
            cout<<"1";
        }
        else{
            cout<<"0";
        }
    }
    cout<<"\n";
}


int main(int argc, char *argv[])
{







    // //不用waitpid等待子进程,子进程退出会向父进程发送17号信号
    // signal(17,SIG_IGN);//把对17号信号的默认处理动作设置为忽略，这样就不用等待了
    // pid_t id = fork();
    // if(id ==0){
    //     printf("我是子进程，pid:%d,ppid:%d\n",getpid(),getppid());
    //     Count(5);
    //     exit(1);
    // }


    



    // signal(3,handler);
    // struct sigaction act,oact;
    // act.sa_handler = handler;
    // act.sa_flags = 0;
    // sigemptyset(&act.sa_mask);
    // //当我们在处理某一种信号的时候，我们也想顺便屏蔽其他的信号，就可以添加到这个sa_mask中

    // sigaddset(&act.sa_mask,3);//
    // sigaction(SIGINT,&act,&oact);
    // while(1){
    //     sleep(1);
    // }







    // for(auto e:sigarr){
    //     signal(e,handler);
    // }

    // // 信号阻塞，尝试阻塞2号信号
    // // 1:先定义要屏蔽的信号
    // sigset_t block, oblock,pending;
    // // 2:初始化
    // sigemptyset(&block);
    // sigemptyset(&oblock);
    // // 3:添加要屏蔽的信号
    // //sigaddset(&block, 2);
    // for(auto e:sigarr){
    //     sigaddset(&block,e);//同时屏蔽vector里面所有的信号
    // }
    // // 4:开始屏蔽，设置进内核
    // sigprocmask(SIG_SETMASK, &block, &oblock);

    // int cnt = 10;
    // while(1){
    //     sigemptyset(&pending);
    //     //2:获取
    //     sigpending(&pending);
    //     show_pending(pending);
    //     sleep(1);
    //     if(cnt-- == 0){
    //         sigprocmask(SIG_SETMASK,&oblock,&block);
    //         cout<<"恢复对所有信号的屏蔽，不屏蔽任何信号"<<endl;
    //     }
        
    // }









    // 3:信号的保存:block,pending位图结构
    //  for(int i = 0;i<31;i++){
    //      signal(i,handler);
    //  }
    //  while(1){
    //      cout<<"running 。。。"<<getpid()<<endl;
    //      sleep(1);
    //  }

    // 2:信号产生的方式：

    // signal(SIGALRM,handler);

    // //d,软件条件产生信号
    // alarm(1);//定一个闹钟，1s后会响，默认的动作是终止进程

    // while(1){
    //     cnt++;
    // }

    // //c,硬件异常产生
    // while(1){
    //     cout<<"running ..."<<endl;
    //     sleep(1);
    //     // int a = 10;
    //     // a/=0;//除0错误

    //     int* p =nullptr;
    //     *p =100;//0号地址是不能被访问的
    // }

    // b，kill系统调用
    // 自己封装实现一个kill，试着朝其他进程发送kill信号
    //./my_signal pid sign
    //  if(argc!=3){
    //      errno_print(argv[0]);
    //      exit(1);
    //  }

    // pid_t id = atoi(argv[1]);
    // int sig = atoi(argv[2]);

    // int n = kill(id,sig);
    // assert(n == 0);

    // raise:给自己的进程发送任意信号
    //  int cnt = 0;
    //  while(cnt <= 10){
    //      cout<<"cnt:"<<cnt<<endl;
    //      cnt++;
    //      sleep(1);
    //      if(cnt >= 5) abort();//向自己的进程发送6号信号
    //      //kill(getpid(),2);
    //      //raise(3);
    //  }

    // a，热键

    // 捕捉2号信号
    //  signal(2,handler);

    // while(1){
    //     cout<<"我是一个进程："<<getpid()<<endl;
    //     sleep(1);
    // }

    return 0;
}